﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MachineStatusClient
{
    public class LargeCalendarDateTimePicker : DateTimePicker
    {
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [DllImport("user32.dll")]
        private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll")]
        private static extern IntPtr GetParent(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        private const uint GW_CHILD = 5;
        private const int MONTHCAL_CLASS = 0;
        private string MONTHCAL_CLASSNAME = "SysMonthCal32";

        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        private float _scaleFactor = 1.5f;
        public float ScaleFactor
        {
            get { return _scaleFactor; }
            set
            {
                _scaleFactor = Math.Max(1.0f, Math.Min(3.0f, value));
            }
        }

        // 添加一个标志来跟踪是否已经调整大小
        private bool _calendarResized = false;

        public LargeCalendarDateTimePicker()
        {
            // 确保在下拉时处理大小调整
            this.DropDown += LargeCalendarDateTimePicker_DropDown;
        }

        private void LargeCalendarDateTimePicker_DropDown(object sender, EventArgs e)
        {
            _calendarResized = false;

            // 使用定时器检查日历控件何时可用
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Interval = 10;
            timer.Tick += (s, args) =>
            {
                if (!_calendarResized)
                {
                    if (TryResizeCalendar())
                    {
                        _calendarResized = true;
                        timer.Stop();
                        timer.Dispose();
                    }
                }
                else
                {
                    timer.Stop();
                    timer.Dispose();
                }
            };
            timer.Start();
        }

        private bool TryResizeCalendar()
        {
            try
            {
                // 方法1: 直接查找日历控件
                IntPtr calendarHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, MONTHCAL_CLASSNAME, null);

                // 方法2: 如果方法1失败，尝试通过父窗口查找
                if (calendarHandle == IntPtr.Zero)
                {
                    IntPtr dropDownHandle = GetParent(this.Handle);
                    if (dropDownHandle != IntPtr.Zero)
                    {
                        calendarHandle = FindWindowEx(dropDownHandle, IntPtr.Zero, MONTHCAL_CLASSNAME, null);
                    }
                }

                // 方法3: 如果以上方法都失败，使用传统方法
                if (calendarHandle == IntPtr.Zero)
                {
                    calendarHandle = GetWindow(this.Handle, GW_CHILD);
                }

                if (calendarHandle != IntPtr.Zero)
                {
                    // 获取当前日历的大小
                    GetWindowRect(calendarHandle, out RECT rect);
                    int width = rect.Right - rect.Left;
                    int height = rect.Bottom - rect.Top;

                    // 计算新的尺寸
                    int newWidth = (int)(width * ScaleFactor);
                    int newHeight = (int)(height * ScaleFactor);

                    // 获取屏幕工作区大小
                    Rectangle screen = Screen.GetWorkingArea(this);

                    // 检查是否会超出屏幕
                    if (rect.Right + (newWidth - width) > screen.Right)
                    {
                        newWidth = screen.Right - rect.Left;
                    }

                    if (rect.Bottom + (newHeight - height) > screen.Bottom)
                    {
                        newHeight = screen.Bottom - rect.Top;
                    }

                    // 重新定位和调整大小
                    bool success = MoveWindow(calendarHandle, rect.Left, rect.Top, newWidth, newHeight, true);

                    if (success)
                    {
                        // 同时调整下拉窗口的大小
                        IntPtr dropDownHandle = GetParent(calendarHandle);
                        if (dropDownHandle != IntPtr.Zero)
                        {
                            GetWindowRect(dropDownHandle, out RECT dropDownRect);
                            int dropDownWidth = dropDownRect.Right - dropDownRect.Left;
                            int dropDownHeight = dropDownRect.Bottom - dropDownRect.Top;

                            int newDropDownWidth = dropDownWidth + (newWidth - width);
                            int newDropDownHeight = dropDownHeight + (newHeight - height);

                            MoveWindow(dropDownHandle, dropDownRect.Left, dropDownRect.Top,
                                      newDropDownWidth, newDropDownHeight, true);
                        }

                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("调整日历时出错: " + ex.Message);
            }

            return false;
        }

        // 重写WndProc方法以捕获日历消息
        protected override void WndProc(ref Message m)
        {
            // 0x0114 - WM_HSCROLL
            // 0x0115 - WM_VSCROLL
            // 这些消息可能表示日历内容已更新，可能需要重新调整大小
            if (m.Msg == 0x0114 || m.Msg == 0x0115)
            {
                if (!_calendarResized)
                {
                    TryResizeCalendar();
                }
            }

            base.WndProc(ref m);
        }
    }
}
